package org.third.common.utils.rest;

import org.springframework.http.HttpRequest;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.client.support.HttpRequestWrapper;

import java.io.IOException;
import java.util.Collections;
import java.util.List;

/**
 * Modifies an outgoing HTTP request to add the Accept header.
 */
public class AcceptHeaderHttpRequestInterceptor implements ClientHttpRequestInterceptor {
    /** The media type to accept in response */
    private final MediaType mediaType;

    /**
     * Creates a new instance of {@link AcceptHeaderHttpRequestInterceptor} given the string name of the desired
     * media type.
     *
     * @param headerValue The string name of the desired media type.
     */
    public AcceptHeaderHttpRequestInterceptor(String headerValue) {
        this.mediaType = MediaType.valueOf(headerValue);
    }

    /**
     * Creates a new instance of {@link AcceptHeaderHttpRequestInterceptor} given the desired media type.
     *
     * @param mediaType The desired media type.
     */
    public AcceptHeaderHttpRequestInterceptor(MediaType mediaType) {
        this.mediaType = mediaType;
    }

    /**
     * Intercepts the given request and returns a response. The given {@link ClientHttpRequestExecution} allows this
     * interceptor to pass on the request and response to the next entry in the chain. This interceptor adds the
     * Accept header to the HTTP request.
     *
     * @param request The request, containing method, URI, and headers.
     * @param body The body of the request.
     * @param execution The request execution
     *
     * @return The response
     *
     * @throws IOException in case of I/O errors
     */
    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body,
                                        ClientHttpRequestExecution execution) throws IOException {
        HttpRequestWrapper requestWrapper = new HttpRequestWrapper(request);
        List<MediaType> mediaTypeList = Collections.singletonList(this.mediaType);
        requestWrapper.getHeaders().setAccept(mediaTypeList);
        return execution.execute(requestWrapper, body);
    }
}
